package com.plian.system.service.ms.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.plian.Tools.DateUtil;
import com.plian.Tools.*;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.common.status.CustomCode;
import com.plian.system.constant.sys.FormStatusConstant;
import com.plian.system.constant.sys.FormTypeConstant;
import com.plian.system.entity.ms.QuarterInspect;
import com.plian.system.mapper.ms.QuarterInspectMapper;
import com.plian.system.model.CommonCode;
import com.plian.system.model.R;
import com.plian.system.mybatis.base.BaseFlowService;
import com.plian.system.mybatis.base.BaseServiceImpl;
import com.plian.system.mybatis.support.Condition;
import com.plian.system.service.ms.IQuarterInspectService;
import com.plian.system.service.sys.code.IFormCodeService;
import com.plian.system.service.sys.file.FileService;
import com.plian.system.service.sys.orgzation.IOrgService;
import com.plian.system.service.sys.orgzation.OrgzationService;
import com.plian.system.service.sys.user.ISysUserService;
import com.plian.system.service.wf.FormWorkflowService;
import com.plian.system.service.yth.IMonthReportService;
import com.plian.system.vo.ms.QuarterInspectVO;
import com.plian.system.wrapper.ms.QuarterInspectWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.poi.ss.usermodel.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;

import static com.plian.system.constant.sys.FormStatusConstant.UNREVIEWED;

/**
 * 季度监督检查报告表 服务实现类
 * @author huzb
 * @create 2020-11-09 14:29
 */
@Slf4j
@Service
@AllArgsConstructor
public class QuarterInspectServiceImpl extends BaseServiceImpl<QuarterInspectMapper, QuarterInspect> implements IQuarterInspectService, BaseFlowService {

    private FormWorkflowService formWorkflowService;

    private IFormCodeService formCodeService;

    private FileService fileService;

    private OrgzationService orgzationService;

    private QuarterInspectMapper quarterInspectMapper;

    private QuarterInspectWrapper quarterInspectWrapper;

    private IMonthReportService monthReportService;

    private IOrgService orgService;

    private ISysUserService userService;
    @Override
    public HashMap<String, Object> commit(String id) {
        handleStatus(Long.valueOf(id), FormStatusConstant.FLOW);

        //将需要提交的流程变量返回，用于工作流侧
        return new HashMap<String,Object>();
    }

    @Override
    public Boolean finish(String id) {
        return handleStatus(Long.valueOf(id), FormStatusConstant.FINISH);
    }

    @Override
    public Boolean reject(String id, int formState, String comment) {
        return handleStatus(Long.valueOf(id), formState);
    }

    @Override
    public Boolean checkIsExisted(Long id, String code) {
        if (Optional.ofNullable(code).isPresent()) {
            QuarterInspect quarterInspect = new QuarterInspect();
            quarterInspect.setCode(code);
            if (Optional.ofNullable(getOne(Condition.getQueryWrapper(quarterInspect))).isPresent()) {
                return id != null && id.equals(getOne(Condition.getQueryWrapper(quarterInspect)).getId());
            }
        }
        return true;
    }

    @Override
    public Boolean submit(QuarterInspect quarterInspect) {
        if (!Optional.ofNullable(quarterInspect.getStatus()).isPresent()){
            quarterInspect.setStatus(FormStatusConstant.UNREVIEWED);
        }
        boolean result = saveOrUpdate(quarterInspect);
         return result;
    }

    @Override
    public Boolean checkCancel(Long id) {
        QuarterInspect quarterInspect = getById(id);
        return Optional.ofNullable(quarterInspect).isPresent();
    }

    @Override
    public boolean saveOrUpdate(QuarterInspect quarterInspect) {
        if (!Optional.ofNullable(quarterInspect.getStatus()).isPresent()) {
            quarterInspect.setStatus(UNREVIEWED);
        }
        boolean flag = false;
        if (!Optional.ofNullable(quarterInspect.getId()).isPresent()) {
            quarterInspect.setCode(formCodeService.getCode(FormTypeConstant.MS_QUARTER_INSPECT));
            quarterInspect.setFormType(String.valueOf(FormTypeConstant.MS_QUARTER_INSPECT));
            flag = true;
        }
        boolean result = super.saveOrUpdate(quarterInspect);
        if (flag){
            fileService.saveAll(String.valueOf(quarterInspect.getId()), quarterInspect.getDocList());
        }else {
            fileService.edit(String.valueOf(quarterInspect.getId()), quarterInspect.getDocList());
        }
        if (flag){
            fileService.upYthFile(quarterInspect.getAttachIds(), quarterInspect.getFormType());
        }
        return result;
    }


    /**
     * 统一处理状态机事件方法
     *
     * @param id          主键
     * @param updateStatus 更新状态
     * @return boolean
     */
    private Boolean handleStatus(Long id, int updateStatus) {
        try {
            QuarterInspect quarterInspect = getById(id);
            /**
             * 设置审批人和审批时间
             */
            if (updateStatus == FormStatusConstant.FINISH){
                quarterInspect.setApprovedUser(TokenUtil.getTokenUserId());
                Date now = DateUtil.now();
                quarterInspect.setApprovedTime(now);
            }
            quarterInspect.setStatus(updateStatus);
            updateById(quarterInspect);
            return true;
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
            return false;
        }
    }

    @Override
    @Transactional(rollbackFor=RuntimeException.class)
    public R initAdd(QuarterInspect quarterInspect) {
        QuarterInspect old = getOne(new QueryWrapper<QuarterInspect>()
                .eq("fill_company_id", TokenUtil.getTokenOrgId())
                .eq("fill_month", quarterInspect.getFillMonth()));
        if (Optional.ofNullable(old).isPresent()){
            return new R(CustomCode.builder().message("该年月已填报").code(1999).success(false).build());
        }
//        quarterInspect.setStatus(FormStatusConstant.STASH);
        boolean result = saveOrUpdate(quarterInspect);
        HashMap<String, Object> processVariable = new HashMap<>();
        formWorkflowService.startProcessAndSimulate(String.valueOf(quarterInspect.getId()),quarterInspect.getFormType(),processVariable);
        return result ? new R(CommonCode.SUCCESS) : new R(CommonCode.FAIL);
    }

    @Override
    public List<PageData> findByIds(List<String> formIds) {

        LambdaQueryWrapper<QuarterInspect> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(QuarterInspect::getId, Func.toLongList(org.apache.commons.lang3.StringUtils.join(formIds, StringPool.COMMA)));
        List<QuarterInspect> quarterInspects = list(queryWrapper);
        List<QuarterInspectVO> quarterInspectVOS = quarterInspectWrapper.entityToVO(quarterInspects);
        List<PageData> pageDataList = new ArrayList<>();
        try{
            if (CollectionUtil.isNotEmpty(quarterInspectVOS)){
                for (QuarterInspectVO vo : quarterInspectVOS){
                    PageData pd = new PageData();
                    pd.put("id", vo.getId());
                    pd.put("UNITNAME", vo.getFillCompanyName());
                    pd.put("APPLICANTNAME", vo.getCreateUserName());
                    pd.put("applicantId", vo.getCreateUser());
                    pd.put("applyOrganizationId", vo.getFillCompanyName());
                    pd.put("formType", FormTypeConstant.MS_QUARTER_INSPECT);
                    pd.put("orgName", vo.getFillCompanyName());
                    pageDataList.add(pd);
                }
            }
            return pageDataList;
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
        }
        return pageDataList;
    }

    @Override
    public List<Integer> getFormType() {
        return Collections.singletonList(FormTypeConstant.MS_QUARTER_INSPECT);
    }

    @Override
    public void goBackToStash(String formId) {
        handleStatus(Long.valueOf(formId), UNREVIEWED);
    }

    @Override
    public List<PageData> orgBydate(PageData pageData) {
        ArrayList<String> orgIds = (ArrayList<String>) pageData.get("orgIds");
        String fillMonth = pageData.getString("fillMonth");
        ArrayList<PageData> pdList = new ArrayList<>();
        for (String orgId:orgIds){
            PageData pd1 = new PageData();
            pd1.put("orgId",orgId);
            pd1.put("fillMonth", fillMonth);
            List<PageData> list = quarterInspectMapper.orgBydate(pd1);
            for (PageData pageData1:list){
                if (pageData1.getString("fillCompanyId") != null){
                    PageData org = orgzationService.getCompanyNameById(pageData1.getString("fillCompanyId"));
                    if (org != null) {
                        pageData1.put("orgName",org.getString("name"));
                    }
                    pdList.add(pageData1);
                }
            }
        }
        return pdList;
    }



    /**
     * 月度计划及总结报表导出
     */
    @Override
    public void exportExcel(List<PageData> pdlist, HttpServletResponse response, OutputStream os)  {
        try {
            String fname = "季度报告汇总导出表";
            os = response.getOutputStream();//取得输出流
            response.reset();//清空输出流
            //下面是对中文文件名的处理
            response.setCharacterEncoding("UTF-8");//设置相应内容的编码格式
            //读取系统中的模板
            InputStream inputStream = this.getClass().getResourceAsStream("/exceldemo/季度报告汇总模板.xlsx");
            //InputStream inputStream = new FileInputStream(new File("C:\\Users\\Administrator\\Desktop\\季度报告汇总模板.xlsx"));
            fname = java.net.URLEncoder.encode(fname, "UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + new String(fname.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8) + ".xls");
            response.setContentType("application/msexcel");//定义输出类型

            //List<PageData> pdlist = (List<PageData>) pd.get("list");
            //多少行
            int row = pdlist.size();
            //克隆模板得到一个新的excel模板
            DynamicOperateExcelUtils dynamicOperateExcelUtils = new DynamicOperateExcelUtils(inputStream);
            //获取工作簿
            Workbook workbook = dynamicOperateExcelUtils.getWorkbook();
            //获取表格
            Sheet sheet = dynamicOperateExcelUtils.getSheet(0);
            CellStyle cellStyle = workbook.createCellStyle();
            //设置样式对象，这里仅设置了边框属性
            cellStyle.setBorderBottom(BorderStyle.THIN);
            cellStyle.setBorderLeft(BorderStyle.THIN);
            cellStyle.setBorderRight(BorderStyle.THIN);
            cellStyle.setBorderTop(BorderStyle.THIN);

            cellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex()); //下边框
            cellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());//左边框
            cellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());//右边框
            cellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());//上边框
            //设置自动换行
            cellStyle.setWrapText(true);
            for (int a = 0; a < row; a++) {
                PageData welfareExpendVO = pdlist.get(a);
                Row row1 = sheet.createRow(a+2);
                //非增行的替换模板单元格的数据
                for (int b = 0; b < 6; b++) {
                    Cell cell = row1.createCell(b);
                    switch (b){
                        case 0: dynamicOperateExcelUtils.replaceCellValue(a + 2, b, welfareExpendVO.getString("orgName"));break;
                        case 1: dynamicOperateExcelUtils.replaceCellValue(a + 2, b, welfareExpendVO.getString("quarterDevelopment"));break;
                        case 2: dynamicOperateExcelUtils.replaceCellValue(a + 2, b, welfareExpendVO.getString("companyMajorIssues"));break;
                        case 3: dynamicOperateExcelUtils.replaceCellValue(a + 2, b, welfareExpendVO.getString("companyBudgetImplement"));break;
                        case 4: dynamicOperateExcelUtils.replaceCellValue(a + 2, b, welfareExpendVO.getString("findMainIssues"));break;
                        case 5: dynamicOperateExcelUtils.replaceCellValue(a + 2, b, welfareExpendVO.getString("issuesRectification"));break;
                        default:break;
                    }
                    cell.setCellStyle(cellStyle);
                }

            }
            dynamicOperateExcelUtils.exportExcel("D:\\excel2.xlsx");
            workbook.write(os);
            os.flush();
            os.close();
            workbook.close();
        } catch (IOException e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
        }
    }
}
